/**
 * @author renato
 * Created on 03/09/2005
 */
package br.unb.graphics;

import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import java.net.URL;

import java.util.Iterator;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;

import br.unb.core.manager.Manager;
import br.unb.core.traffic.Traffic;
import br.unb.utils.Console;
import br.unb.utils.Path;
import br.unb.utils.Resource;

public class TrafficTable {

    private static final String TRAFFIC_ID = "trafficId";
    private static final String TRAFFIC_TYPE = "trafficType";
    private static final String SOURCE_IP = "sourceIP";
    private static final String PORT = "port";
    private static final String DESTINATION_IP = "destinationIP";
    private static final String SIZE = "size";
    private static final String TOS = "tos";
    private static final String BEGIN = "beginning";
    private static final String END = "end";
    private InterfaceFactory ifactory;
    public Action[] actions = new Action[]{
        new PlayTrafficAction(),
        new PlayRealTrafficAction(),
        new DeleteTrafficAction()
    };
    private JScrollPane scrollpane;
    private JTable tableView;
    private String[] columnNames = new String[12];
    private int countLine;
    private Object[][] data = {
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""},
        {"", "", "", "", "", "", "", "", "", "", "", ""}};

    public TrafficTable() {
        ifactory = new InterfaceFactory(Resource.TrafficTable);

        columnNames[0] = ifactory.getResourceString(TrafficTable.TRAFFIC_ID);
        columnNames[1] = ifactory.getResourceString(TrafficTable.TRAFFIC_TYPE);
        columnNames[2] = ifactory.getResourceString(TrafficTable.SOURCE_IP);
        columnNames[3] = ifactory.getResourceString(TrafficTable.PORT);
        columnNames[4] = ifactory.getResourceString(TrafficTable.DESTINATION_IP);
        columnNames[5] = ifactory.getResourceString(TrafficTable.PORT);
        columnNames[6] = ifactory.getResourceString(TrafficTable.SIZE);
        columnNames[7] = ifactory.getResourceString(TrafficTable.TOS);
        columnNames[8] = ifactory.getResourceString(TrafficTable.BEGIN);
        columnNames[9] = ifactory.getResourceString(TrafficTable.END);
        columnNames[10] = "s";
        columnNames[11] = "r";

        tableView = new JTable(data, columnNames);
        tableView.addMouseListener(new PopupListener(createPopupMenu()));
        tableView.addFocusListener((FocusListener) new myFocuListener(this));

        scrollpane = new JScrollPane(tableView);
    }

    public JScrollPane getPanel() {
        return scrollpane;
    }

    /**
     * Updates the table, shows the information of the TrafficMessages.trafficMap.
     */
    public void updateData() {
        Iterator it = Manager.getTrafficMap().keySet().iterator();
        countLine = 0;
        while (it.hasNext()) {
            Traffic t = (Traffic) Manager.getTrafficMap().get((String) it.next());
            setLineAt(countLine, t);
            countLine++;
        }

        for (int i = countLine; i < tableView.getRowCount(); i++) {
            for (int j = 0; j < tableView.getColumnCount(); j++) {
                tableView.setValueAt("", i, j);
            }
        }
    }

    /**
     * Fills a line with a traffic controller data
     * @param index
     * @param traffic
     */
    public void setLineAt(int index, Traffic traffic) {
        if (index < tableView.getRowCount()) {
            tableView.setValueAt(traffic.getName(), index, 0);
            tableView.setValueAt(traffic.getPauseType(), index, 1);
            tableView.setValueAt(traffic.getSrcIP(), index, 2);
            tableView.setValueAt(traffic.getSrcPort() + "", index, 3);
            tableView.setValueAt(traffic.getDstIP(), index, 4);
            tableView.setValueAt(traffic.getDstPort() + "", index, 5);
            tableView.setValueAt(traffic.getLengthType() + "", index, 6);
            tableView.setValueAt(traffic.getTos() + "", index, 7);
            tableView.setValueAt(traffic.getStart() + "", index, 8);
            tableView.setValueAt(traffic.getDuration() + "", index, 9);
        }
    }

    private JPopupMenu createPopupMenu() {
        JMenuItem startItem, startRealItem, deleteItem;
        Action[] ac = ControlComponent.getInstance().getActions();
        //Create the popup menu.
        JPopupMenu popup = new JPopupMenu();
        //TODO use interfaceFactory here, or another way but not action[index]
        startItem = createMenuItem("play");
        startItem.addActionListener(actions[0]);

        startRealItem = createMenuItem("playReal");
        startRealItem.addActionListener(actions[1]);

        deleteItem = createMenuItem("delete");
        deleteItem.addActionListener(actions[2]);

        popup.add(startItem);
        popup.add(startRealItem);
        popup.add(deleteItem);
        return popup;
    }

    protected JMenuItem createMenuItem(String label) {
        JMenuItem mi = new JMenuItem(label);
        URL url = Path.getResourceUrlByAddress("16x16/" + label + ".png");
        if (url != null) {
            // url = this.getClass().getResource(url.toString());
            mi.setHorizontalTextPosition(JButton.RIGHT);
            mi.setIcon(new ImageIcon(url));
        }
        return mi;
    }

    class PopupListener extends MouseAdapter {

        JPopupMenu popup;

        PopupListener(JPopupMenu popupMenu) {
            popup = popupMenu;
        }

        public void mousePressed(MouseEvent e) {
            maybeShowPopup(e);
        }

        public void mouseReleased(MouseEvent e) {
            maybeShowPopup(e);
        }

        private void maybeShowPopup(MouseEvent e) {
            int index = tableView.getSelectedRow();
            if (index >= 0 && index < countLine) {
                if (e.isPopupTrigger()) {
                    popup.show(e.getComponent(),
                            e.getX(), e.getY());
                }
            } else {
                //Resource.showMessageDialog(
                Console.printError(
                        Resource.getString("SELECT_VALID_TRAFFIC"));
            }
        }
    }

    public class myFocuListener implements FocusListener {

        TrafficTable tt;

        public myFocuListener(TrafficTable t) {
            tt = t;
        }

        public void focusGained(FocusEvent e) {
            tt.updateData();
        }

        public void focusLost(FocusEvent e) {
            tt.updateData();
        }
    }

    /*********************************************************************/
    /*********************         ACTIONS           *********************/
    /*********************************************************************/
    public class PlayTrafficAction extends AbstractAction {

        public PlayTrafficAction() {
            super("PlayTrafficAction");
        }

        public void actionPerformed(ActionEvent e) {
            String trafficName = (String) tableView.getValueAt(tableView.getSelectedRow(), 0);
            Manager.getInstance().playGenericTraffic(trafficName, false);
            GraphicInterface.getInstance().startLoadingBar();
        }
    }

    public class PlayRealTrafficAction extends AbstractAction {

        public PlayRealTrafficAction() {
            super("PlayRealTrafficAction");
        }

        public void actionPerformed(ActionEvent e) {
            String trafficName = (String) tableView.getValueAt(tableView.getSelectedRow(), 0);
            Manager.getInstance().playGenericTraffic(trafficName, true);
            GraphicInterface.getInstance().startLoadingBar();
        }
    }

    public class DeleteTrafficAction extends AbstractAction {

        public DeleteTrafficAction() {
            super("DeleteTrafficAction");
        }

        public void actionPerformed(ActionEvent e) {
            String trafficName = (String) tableView.getValueAt(tableView.getSelectedRow(), 0);
            Manager.getInstance().stopTraffic(trafficName);
            GraphicInterface.getInstance().stopLoadingBar();
        }
    }
}
